cc-pocket · mobile ui 2.0 · session · git tab · v1

Session Git Tab v1

A third tab beside Files and Diff, so the review that already happens on the phone can end in a commit and a push instead of a walk back to the computer. Owner-only. Every operation is a tap on a closed allow-list — stage, unstage, commit, fetch, pull --ff-only, push, checkout, branch, revert file. No free-text command ever reaches the machine.

390 × 844
dark · 1:1
4 screens
13 frames
9 verbs
allow-list

The index is the whole model. Staged, Changes, Untracked, Conflicts are the only groups, in that order, and a row belongs to exactly one. Nothing is summarised into a count the user has to trust.

One glyph, one colour, one meaning. Green is staged, amber is a working change, red is a conflict, grey is untracked. The chip carries the letter git already uses, so the panel teaches nothing new.

The composer is pinned, the list scrolls. Commit is always reachable without scrolling, and the three remote verbs sit under it where they cannot be hit by mistake while staging.

The phone declines what it cannot do well. Merges, rebases and conflict resolution are named and handed back to the computer rather than half-built here.

A

Screen A · Git status panel

The anchor. Seven states of one layout: repo header, grouped list, pinned composer.
A1 · canonical · message typed

Branch, divergence and upstream in three facts on two lines; the whole block is the doorway to the branch sheet, with refresh as its own 44 pt target. Long paths middle-truncate from the left so the filename never moves. Counts sit under the path rather than beside it, which keeps the action pill at a fixed right edge down the whole list.

A2 · clean tree

Empty sections are removed, not shown empty. The composer stays visible and disabled so the surface does not change shape between states, and the caption answers the only question left: when was this last true, and against what.

A3 · conflicts present

Conflicts take the top of the list and Staged disappears, because nothing can be staged while the index is unmerged. Conflict rows carry no action pill — only a chevron to the diff — and the disabled Commit is explained in place rather than by a toast.

A4 · push in flight

The spinner lives in the button that started the work, the label states the verb in progress, and the count drops because it is no longer a promise. Nothing else locks: staging can continue while the push runs.

A5 · push failed · non-blocking

One sentence of ours, then the first line of git's stderr verbatim in mono. A developer recognises (fetch first) instantly, and we do not try to translate it. Dismissible, and the composer keeps working underneath.

A6 · pull refused · not fast-forward

The refusal is the feature. Amber rather than red, because nothing is broken and nothing was lost; the strip names the destination — the computer — instead of offering a merge the phone should not be running.

A7 · loading

The skeleton holds the real geometry — section label, chip, path, trailing action — so the list does not jump when status arrives. Branch name is already known from the session, so only the counters and the rows are unresolved.

B

Screen B · File diff

The existing diff viewer, plus one segmented control and one overflow item.
B1 · working side

Unchanged from today's viewer: dark code field, hunk headers, gutter numbers, added and removed lines tinted rather than only signed. The path takes the title, the Diff tab stays lit, and the totals sit opposite the segmented control instead of adding a row.

B2 · staged side

Working / Staged is the one new control, and it answers the question the panel creates: what exactly will this commit contain. The totals change with the side, which is how the user sees that a partially staged file has two truths.

B3 · overflow · revert file

The destructive verb is one level down, last in the menu, in danger ink, with a trailing ellipsis promising a second step. It leads to D. Nothing in the menu acts immediately.

C

Screen C · Branch sheet

Raised from the repo header. Local branches only.
C1 · list

Current branch first with a check and the word current; everything else is ordered by last commit, which is the order people actually think in. New branch… sits above the list in accent because creating is safe, while every other row is a checkout that may not be.

C2 · new branch expanded

The row expands in place rather than pushing a screen, and its label states the base branch so the one fact a name cannot carry is present. Create is the only filled control in the sheet.

D · destructive confirm · shared

One sheet for both losses: revert file, and checkout with a dirty tree. Count in the title, the exact paths in mono with their counts, then the sentence that says what survives. Discard is filled danger and sits right, Cancel is quiet and sits left, and the whole thing reads in a breath.

E

Allow-list contract

Nine verbs. Anything absent from this table is not reachable from the phone.
VerbEntryGuardNever
{{ v.verb }} {{ v.entry }} {{ v.guard }} {{ v.never }}

Two-step is reserved. Only revert file and dirty checkout raise D. Unstage, fetch and a refused pull are all recoverable in one tap, so a confirmation there would only teach people to dismiss confirmations.

Errors are quoted, not paraphrased. The first stderr line goes on screen in mono. Our own sentence above it says what happened in product terms; we never rewrite git's words into something a search engine cannot match.

Open questions. Bulk Stage all / Unstage all per section is not drawn here and needs a decision. Hunk-level staging is deliberately out. Amend, stash and force-push are absent by design.